from flask import abort, jsonify, request
from info.utils.response_code import RET
from . import news_bp
from flask import render_template
from flask import current_app, session
from info import constants, db
from info.models import User, News, Comment
from flask import g
from info.utils.common import login_user_data


@news_bp.route("/<int:news_id>")
@login_user_data
def news_detail(news_id):
    # ----------1. 当用户登录成功后可以使用session 对象获取里面的用户user_id-------------
    # user_id = session.get("user_id")
    # # 2. 根据user_id查询用户对象
    # user = None  # type:User
    # try:
    #
    #     if user_id:
    #         user = User.query.get(user_id)
    # except Exception as e:
    #     current_app.logger.error(e)
    user = g.user

    # ----2.查询新闻的点击排行数据-----
    # 1.根据浏览量查询6条点击排行的新闻数据
    try:
        news_model_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)

    # 3. 将模型列表转成字典列表
    news_dict_list = []
    for news in news_model_list if news_model_list else []:
        # 获取到news对象调用to_dict方法将对象转换成字典,再添加到news_model_list中
        news_dict_list.append(news.to_dict())

    # -----------3.查询新闻的详情数据------------
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)

    if not news:
        abort(404)
    # 每浏览一次,点击量就加一
    news.clicks += 1
    print(news.clicks)

    # 将模型的修改提交到数据库
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.rollback()
        abort(404)

    # ---------4.查询用户是否收藏过该新闻------------
    is_collected = False

    if user:
        if news in user.collection_news:
            # news在用户的收藏的新闻列表内,表示用户收藏过该新闻,is_collected该成True
            is_collected = True

    # ----------------5.查询新闻的评论列表数据----------------------------
    comments = []
    try:
        # 查询对应新闻的评论列表 [comment1 comment2]
        comments = Comment.query.filter(Comment.news_id==news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
        # 模型列表转字典列表
    comment_dict_list = []
    for comment in comments if comments else []:
        comment_dict_list.append(comment.to_dict())


    data = {
        "user_info": user.to_dict() if user else None,
        "newsClickList": news_model_list,
        "news": news.to_dict(),
        "is_collected": is_collected,
        "comments":comment_dict_list
    }
    return render_template("news/detail.html", data=data)


@news_bp.route("/news_collect", methods=['POST'])
@login_user_data
def news_collect():
    """收藏和取消收藏接口"""
    """
    1. 获取参数
        1.1 用户对象 新闻id action:(收藏或者取消收藏)
    2. 校验参数
        2.1 非空判断
        2.2 用户是否登录
        2.3 action的值判断
    3. 逻辑实现
        3.1 根据新闻id查询该新闻
        3.2 取消收藏:将新闻对象从news_collection 中取消
        3.3 收藏: 将新闻添加到news_collection中
        3.4 提交修改操作到数据库
    4. 返回值处理
    """
    # 1.1 用户对象 新闻id action:(收藏或者取消收藏)
    params_dict = request.json
    user = g.user
    news_id = params_dict.get("news_id")
    action = params_dict.get("action")

    # 2.1 非空判断
    if not all([user, news_id, action]):
        print(user)
        print()
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")

    # 2.2 用户是否登录
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户不存在")

    # 2.3 action的值判断
    if action not in ["collect", "cancel_collect"]:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 3.1 根据新闻id查询该新闻
    news = None
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻数据异常")

    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在")

    # 收藏
    if action == "collect":
        # 3.2 收藏: 把新闻放到收藏列表
        print(news)
        user.collection_news.append(news)
    else:
        print("haha")
        user.collection_news.remove(news)

    # 3.4 提交修改操作到数据库
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        print(user)
        print(news_id)
        print(action)
        return jsonify(errno=RET.DBERR, errmsg="提交数据到数据库异常")
    # 4. 组织响应数据
    return jsonify(errno=RET.OK, errmsg="OK")


@news_bp.route("/news_comment", methods=["POST"])
@login_user_data
def news_comment():
    """评论接口(主评论 子评论)"""
    """
    1. 获取参数
        1.1 用户对象 新闻id 评论内容 parent_id(主评论id)
    2. 校验参数
        2.1 非空判断
        2.2 判断用户是否登录
    3. 逻辑处理
        3.1 根据新闻id查询该新闻(新闻存在才能去评论)
        3.2 创建评论模型 给各个属性赋值
        3.3 判断parent_id是否有值
        3.4 将模型对象保存到数据库
    4. 返回值处理
    """
    # 1.1 用户对象 新闻id 评论内容 parent_id(主评论id)
    params_dict = request.json
    news_id = params_dict.get("news_id")
    comment = params_dict.get("comment")
    parent_id = params_dict.get("parent_id")
    user = g.user

    # 2.1 非空判断
    if not all([news_id, comment]):
        print(news_id)
        print(comment)
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 2.2 判断用户是否登录
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    # 3.1 根据新闻id查询该新闻(新闻存在才能去评论)
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在不能评论")

    # 3.1 创建评论模型 给各个属性赋值
    comment_obj = Comment()
    comment_obj.user_id = user.id
    comment_obj.news_id = news.id
    comment_obj.content = comment

    # 3.3 判断parent_id是否有值
    if parent_id:
        # parent_id有值表示是子评论
        comment_obj.parent_id = parent_id

    # 3.4 将模型对象保存到数据库
    try:
        db.session.add(comment_obj)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存评论对象到数据库异常")

    # 4. 组织响应对象
    return jsonify(errno=RET.OK, errmsg="评论成功", data=comment_obj.to_dict())
